using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace SMS.WinForms.Controls
{
    /// <summary>
    /// The <see cref="SMS.WinForms.Controls.WizardPage"/> class defines the base control used to create pages in the
    /// <see cref="SMS.WinForms.WizardForm"/> form.
    /// </summary>
    public partial class WizardPage : UserControl
    {
        #region Declarations

        /// <summary>
        /// Stores the settings for the page.
        /// </summary>
        private WizardPageSettings _pageSettings;

        /// <summary>
        /// Stores the navigation settings for the page.
        /// </summary>
        private WizardPageNavigationSettings _navigationSettings;

        /// <summary>
        /// Stores the DefaultFocus value.
        /// </summary>
        private Control _defaultFocus;

        /// <summary>
        /// Raised when the user interface of the <see cref="SMS.WinForms.WizardForm"/> needs to be updated.
        /// </summary>
        public event EventHandler UpdateWizardSettingsRequired;

        /// <summary>
        /// Stores whether the wizard buttons are disabled.
        /// </summary>
        private Boolean _wizardButtonsDisabled = false;

        /// <summary>
        /// Stores the owner wizard form.
        /// </summary>
        private WizardForm _owner = null;

        /// <summary>
        /// Raised when the page is about to be the current page in the owning
        /// <see cref="SMS.WinForms.WizardForm"/>.
        /// </summary>
        public event EventHandler Opening;

        /// <summary>
        /// Raised when the page is has been made the current page in the owning
        /// <see cref="SMS.WinForms.WizardForm"/>.
        /// </summary>
        public event EventHandler Opened;

        /// <summary>
        /// Raised when the page is about to be removed as the current page in the owning
        /// <see cref="SMS.WinForms.WizardForm"/>.
        /// </summary>
        public event EventHandler Closing;

        /// <summary>
        /// Raised when the page has been removed as the current page in the owning
        /// <see cref="SMS.WinForms.WizardForm"/>.
        /// </summary>
        public event EventHandler Closed;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="SMS.WinForms.Controls.WizardPage"/> class.
        /// </summary>
        public WizardPage()
            : this(null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SMS.WinForms.Controls.WizardPage"/> class.
        /// </summary>
        /// <param name="owner">The owner.</param>
        public WizardPage(WizardForm owner)
        {
            InitializeComponent();

            // Assign the owner
            _owner = owner;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Raises the <see cref="E:UpdateWizardSettingsRequiredRequired"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public void OnUpdateWizardSettingsRequiredRequired(EventArgs e)
        {
            // Check if there is a handler
            if (UpdateWizardSettingsRequired != null)
            {
                // Raise the event
                UpdateWizardSettingsRequired(this, e);
            }
        }

        /// <summary>
        /// Raises the <see cref="E:Opening"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public void OnOpening(EventArgs e)
        {
            // Check if there is a handler
            if (Opening != null)
            {
                // Raise the event
                Opening(this, e);
            }
        }

        /// <summary>
        /// Raises the <see cref="E:Opened"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public void OnOpened(EventArgs e)
        {
            // Check if there is a handler
            if (Opened != null)
            {
                // Raise the event
                Opened(this, e);
            }
        }

        /// <summary>
        /// Raises the <see cref="E:Closing"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public void OnClosing(EventArgs e)
        {
            // Check if there is a handler
            if (Closing != null)
            {
                // Raise the event
                Closing(this, e);
            }
        }

        /// <summary>
        /// Raises the <see cref="E:Closed"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public void OnClosed(EventArgs e)
        {
            // Check if there is a handler
            if (Closed != null)
            {
                // Raise the event
                Closed(this, e);
            }
        }

        /// <summary>
        /// Invokes the navigation.
        /// </summary>
        /// <param name="navigationType">Type of the navigation.</param>
        protected void InvokeNavigation(WizardFormNavigationTypes navigationType)
        {
            ValidateOwnerAndPage();

            // Invoke the navigation on the owner
            _owner.GenerateNavigationEvent(navigationType);
        }

        /// <summary>
        /// Invokes the navigation.
        /// </summary>
        /// <param name="navigationKey">The navigation key.</param>
        protected void InvokeNavigation(String navigationKey)
        {
            ValidateOwnerAndPage();

            // Invoke the navigation on the owner
            _owner.GenerateNavigationEvent(WizardFormNavigationTypes.NavigationKey, navigationKey);
        }

        /// <summary>
        /// Validates the owner and page.
        /// </summary>
        private void ValidateOwnerAndPage()
        {
            // Check that the owner exists
            if (_owner == null)
            {
                throw new Exception("The page isn't owned by a WizardForm.");
            }
            // Check that the current page is this page
            else if (this != _owner.CurrentPage)
            {
                throw new Exception("The page invoking the navigation is not the current page.");
            }
        }

        /// <summary>
        /// Determines whether this instance can navigate the specified e.
        /// </summary>
        /// <param name="e">The <see cref="SMS.WinForms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        /// <returns>
        /// 	<item>true</item> if this instance can navigate the specified e; otherwise, <item>false</item>.
        /// </returns>
        public virtual Boolean CanNavigate(WizardFormNavigationEventArgs e)
        {
            return true;
        }

        /// <summary>
        /// Invokes the help navigation.
        /// </summary>
        /// <param name="e">The <see cref="SMS.WinForms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        public virtual void InvokeHelpNavigation(WizardFormNavigationEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Invokes the custom navigation.
        /// </summary>
        /// <param name="e">The <see cref="SMS.WinForms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        public virtual void InvokeCustomNavigation(WizardFormNavigationEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Sets the owner.
        /// </summary>
        /// <param name="owner">The owner.</param>
        internal void SetOwner(WizardForm owner)
        {
            _owner = owner;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the settings.
        /// </summary>
        /// <value>The settings.</value>
        [
            Category("Wizard"),
            Description("The page settings of the wizard page."),
            ReadOnly(true),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
        ]
        public WizardPageSettings PageSettings
        {
            get
            {
                // Check if there is a value
                if (_pageSettings != null)
                {
                    // Return the settings
                    return _pageSettings;
                }

                // Create the settings
                _pageSettings = new WizardPageSettings();

                // Return the settings
                return _pageSettings;
            }
            set
            {
                _pageSettings = value;
            }
        }

        /// <summary>
        /// Gets the current settings.
        /// </summary>
        /// <value>The current settings.</value>
        [
            Browsable(false)
        ]
        public virtual WizardPageSettings CurrentSettings
        {
            get
            {
                // Check if the wizard buttons should be disabled
                if (WizardButtonsDisabled == false)
                {
                    return PageSettings.Clone();
                }
                else
                {
                    // The wizard buttons should be disabled

                    // Get the current settings
                    WizardPageSettings pageSettings = PageSettings.Clone();

                    // Disable all the buttons
                    pageSettings.CancelButtonSettings.Enabled = false;
                    pageSettings.CustomButtonSettings.Enabled = false;
                    pageSettings.HelpButtonSettings.Enabled = false;
                    pageSettings.NextButtonSettings.Enabled = false;
                    pageSettings.PreviousButtonSettings.Enabled = false;

                    // Return the settings
                    return pageSettings;
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the wizard buttons are disabled.
        /// </summary>
        /// <value>
        /// 	<item>true</item> if [wizard buttons disabled]; otherwise, <item>false</item>.
        /// </value>
        [
            Browsable(false)
        ]
        public Boolean WizardButtonsDisabled
        {
            get
            {
                return _wizardButtonsDisabled;
            }
            set
            {
                _wizardButtonsDisabled = value;

                // Update the UI
                OnUpdateWizardSettingsRequiredRequired(new EventArgs());
            }
        }

        /// <summary>
        /// Gets or sets the navigation settings.
        /// </summary>
        /// <value>The navigation settings.</value>
        [
            Category("Wizard"),
            Description("The navigation settings of the wizard page."),
            ReadOnly(true),
            DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
        ]
        public WizardPageNavigationSettings NavigationSettings
        {
            get
            {
                // Check if there is a value
                if (_navigationSettings != null)
                {
                    return _navigationSettings;
                }

                // Create a new object
                _navigationSettings = new WizardPageNavigationSettings();

                // Return the value
                return _navigationSettings;
            }
            set
            {
                _navigationSettings = value;
            }
        }

        /// <summary>
        /// Gets or sets the default focus.
        /// </summary>
        /// <value>The default focus.</value>
        [
            Category("Behaviour"),
            Description("Determines the control that will receive the focus by default."),
            DefaultValue(null)
        ]
        public Control DefaultFocus
        {
            get { return _defaultFocus; }
            set { _defaultFocus = value; }
        }
	
        /// <summary>
        /// Gets the current navigation settings.
        /// </summary>
        /// <value>The current navigation settings.</value>
        [
            Browsable(false)
        ]
        public virtual WizardPageNavigationSettings CurrentNavigationSettings
        {
            get
            {
                return NavigationSettings;
            }
        }

        /// <summary>
        /// Gets the state.
        /// </summary>
        /// <value>The state.</value>
        [
            Browsable(false)
        ]
        protected Dictionary<String, Object> State
        {
            get
            {
                if (_owner != null)
                {
                    return _owner.State;
                }
                else
                {
                    throw new Exception("Control is not hosted by a WizardForm.");
                }
            }
        }

        #endregion
    }
}
